{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "deb4a99c-3de0-441d-9fcd-d9f373c1e06d",
   "metadata": {},
   "source": [
    "# Bitwise And\n",
    "\n",
    "The Bitwise And (denoted as '&') is implemented by applying this truth table between each pair of qubits in register A and B (or qubit and bit).\n",
    "\n",
    "<center>\n",
    "\n",
    "|  a  |  b  | a & b |\n",
    "| :-: | :-: | :---: |\n",
    "|  0  |  0  |   0   |\n",
    "|  0  |  1  |   0   |\n",
    "|  1  |  0  |   0   |\n",
    "|  1  |  1  |   1   |\n",
    "\n",
    "</center>\n",
    "\n",
    "Note that integer and fixed-point numbers are represented in a two-complement method during function evaluation.\n",
    "The binary number is extended in the case of a register size mismatch.\n",
    "\n",
    "For example, the positive signed number $(110)_2=6$ is expressed as $(00110)_2$ when operating with a five-qubit register.\n",
    "Similarly, the negative signed number $(110)_2=-2$ is expressed as $(11110)_2$.\n",
    "\n",
    "Examples:\n",
    "\n",
    "5 & 3 = 1 since 101 & 011 = 001\n",
    "\n",
    "5 & -3 = 5 since 0101 & 1101 = 0101\n",
    "\n",
    "-5 & -3 = -7 since 1011 & 1101 = 1001"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c39533b4-a023-4d35-bbb8-9f2fb49be987",
   "metadata": {},
   "source": [
    "# Examples\n",
    "\n",
    "#### Example 1: Two Quantum Variables\n",
    "\n",
    "This example generates a quantum program that performs a bitwise 'and' between two variables, both are unsigned integer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "32c35c64-07d7-4244-a2b1-436c983289aa",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:22:21.420338Z",
     "iopub.status.busy": "2024-05-07T13:22:21.419868Z",
     "iopub.status.idle": "2024-05-07T13:22:24.317317Z",
     "shell.execute_reply": "2024-05-07T13:22:24.316490Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import Output, QArray, QBit, QNum, create_model, prepare_int, qfunc\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def main(a: Output[QNum], b: Output[QNum], res: Output[QNum]) -> None:\n",
    "    prepare_int(4, a)\n",
    "    prepare_int(5, b)\n",
    "    res |= a & b\n",
    "\n",
    "\n",
    "qmod = create_model(main)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0eb01ba2-361a-4407-9373-960c6b28c531",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:22:24.321220Z",
     "iopub.status.busy": "2024-05-07T13:22:24.320674Z",
     "iopub.status.idle": "2024-05-07T13:22:27.276315Z",
     "shell.execute_reply": "2024-05-07T13:22:27.275546Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'a': 4.0, 'b': 5.0, 'res': 4.0}: 1000]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from classiq import execute, synthesize, write_qmod\n",
    "\n",
    "write_qmod(qmod, \"bitwise_and_2vars_example\")\n",
    "qprog = synthesize(qmod)\n",
    "\n",
    "result = execute(qprog).result()[0].value\n",
    "result.parsed_counts"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3e6b1f8-b444-4ec5-af53-16a6e3c46c52",
   "metadata": {},
   "source": [
    "#### Example 2: Integer and Quantum Variable\n",
    "\n",
    "This example generates a quantum program that performs a bitwise 'and' between a quantum variable and an integer.\n",
    "The left arg is an integer equal to 3\n",
    "and the right arg is an unsigned quantum variable with three qubits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3c8565b2-eaf1-4315-b748-e128c9f613b8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:22:27.281335Z",
     "iopub.status.busy": "2024-05-07T13:22:27.280094Z",
     "iopub.status.idle": "2024-05-07T13:22:27.291387Z",
     "shell.execute_reply": "2024-05-07T13:22:27.290656Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import Output, QArray, QBit, QNum, create_model, prepare_int, qfunc\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def main(a: Output[QNum], res: Output[QNum]) -> None:\n",
    "    prepare_int(5, a)\n",
    "    res |= 3 & a\n",
    "\n",
    "\n",
    "qmod = create_model(main)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c9ac0055-0f2a-4a6e-9390-632fd241f28d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:22:27.296074Z",
     "iopub.status.busy": "2024-05-07T13:22:27.294936Z",
     "iopub.status.idle": "2024-05-07T13:22:29.730047Z",
     "shell.execute_reply": "2024-05-07T13:22:29.729335Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'a': 5.0, 'res': 1.0}: 1000]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from classiq import execute, synthesize, write_qmod\n",
    "\n",
    "write_qmod(qmod, \"bitwise_and_integer_example\")\n",
    "qprog = synthesize(qmod)\n",
    "\n",
    "result = execute(qprog).result()[0].value\n",
    "result.parsed_counts"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
